package com.example

import java.awt.Color
import java.awt.geom.AffineTransform
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import java.io.File
/**
 * 这个类的作用是可视化数据结构，将把数据具象化到一个Png图片中。
 */
object QTreeRender {
  def renderQuadtree(root: QuadTree, size: Int, outputPath: String, routes: List[(Int, Int)]): Unit = {
    val img = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB)
    val g = img.createGraphics()
    // 重要：图片默认的原点在左上，我们把原点放到左下。
    // transform创建变换：平移并缩放y轴。
    val at: AffineTransform = new AffineTransform();
    at.concatenate(AffineTransform.getScaleInstance(1, -1)); // y轴翻转
    at.concatenate(AffineTransform.getTranslateInstance(0, -512));
    g.transform(at)

    // 递归渲染函数
    def render(node: QuadTree, x: Int, y: Int, width: Int, height: Int): Unit = node match {
      case l: Leaf =>
        g.setColor(if (l.state == Obstacle) Color.BLACK else Color.WHITE)
        g.fillRect(x, y, width, height)
        g.setColor(Color.lightGray)
        g.drawRect(x, y, width, height)
        g.setColor(Color.green)
        val centerPoints = l.neighbors.map {
          case lf:Leaf => (lf.bound.x + lf.bound.size / 2, lf.bound.y + lf.bound.size/2)
          case _ => (0, 0)
        }
        val thisCenter = (l.bound.x + l.bound.size / 2, l.bound.y + l.bound.size/2)
        centerPoints.foreach( a => {
          g.drawLine(thisCenter._1, thisCenter._2, a._1, a._2)
        })
      case n :Node =>
        val halfWidth = width / 2
        val halfHeight = height / 2
        // 假设子节点顺序是: 左上、右上、左下、右下
        render(n.nw, x, y, halfWidth, halfHeight)
        render(n.ne, x + halfWidth, y, halfWidth, halfHeight)
        render(n.sw, x, y + halfHeight, halfWidth, halfHeight)
        render(n.se, x + halfWidth, y + halfHeight, halfWidth, halfHeight)
    }

    render(root, 0, 0, size, size)

    // test!
    //    g.setColor(Color.green)
    //    g.drawLine(64, 64, 32, 160)
    //    g.drawRect(0, 128 ,64 ,64)

    if (routes.nonEmpty) {
      g.setColor(Color.blue)
      val pathIterator = routes.iterator
      var prevPoint = pathIterator.next()

      while (pathIterator.hasNext) {
        val currentPoint = pathIterator.next()

        // 绘制线段
        val x1 = prevPoint._1
        val y1 = prevPoint._2
        val x2 = currentPoint._1
        val y2 = currentPoint._2
        g.drawLine(x1, y1, x2, y2)

        prevPoint = currentPoint
      }
    }


    g.dispose()

    ImageIO.write(img, "png", new File(outputPath))
  }

}
